#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
字典服务 - 提供字典数据的查询、缓存和格式化功能
"""

from app import db
from app.models.dictionary import DictCategory, DictItem
from typing import List, Dict, Optional, Any
import json


class DictService:
    """字典服务类"""
    
    # 用户资料相关的字典分类
    USER_PROFILE_DICTS = [
        'education', 'marital_status', 'occupation', 'income_range',
        'housing_status', 'car_status', 'smoking_habit', 'drinking_habit',
        'personality_traits', 'hobbies'
    ]
    
    # 择偶条件相关的字典分类
    MATE_CRITERIA_DICTS = [
        'income_requirement', 'education_requirement', 'occupation_requirement',
        'marital_requirement', 'housing_requirement', 'smoking_requirement',
        'drinking_requirement'
    ]
    
    @classmethod
    def get_all_categories(cls) -> List[Dict[str, Any]]:
        """获取所有字典分类列表"""
        try:
            categories = DictCategory.query.filter_by(is_active=True)\
                                         .order_by(DictCategory.sort_order)\
                                         .all()
            
            result = []
            for category in categories:
                category_data = category.to_dict()
                # 添加分类用途标识
                if category.dict_code in cls.USER_PROFILE_DICTS:
                    category_data['usage'] = 'user_profile'
                elif category.dict_code in cls.MATE_CRITERIA_DICTS:
                    category_data['usage'] = 'mate_criteria'
                else:
                    category_data['usage'] = 'common'
                
                result.append(category_data)
            
            return result
            
        except Exception as e:
            print(f"获取字典分类列表失败: {str(e)}")
            return []
    
    @classmethod
    def get_dict_items(cls, dict_code: str) -> List[Dict[str, Any]]:
        """根据字典编码获取字典项列表"""
        try:
            category = DictCategory.query.filter_by(
                dict_code=dict_code, 
                is_active=True
            ).first()
            
            if not category:
                return []
            
            items = DictItem.query.filter_by(
                dict_id=category.id, 
                is_active=True
            ).order_by(DictItem.sort_order).all()
            
            return [item.to_dict() for item in items]
            
        except Exception as e:
            print(f"获取字典项列表失败: {str(e)}")
            return []
    
    @classmethod
    def get_user_profile_dicts(cls) -> Dict[str, List[Dict[str, Any]]]:
        """获取用户资料相关的所有字典"""
        try:
            result = {}
            
            for dict_code in cls.USER_PROFILE_DICTS:
                items = cls.get_dict_items(dict_code)
                if items:
                    result[dict_code] = items
            
            return result
            
        except Exception as e:
            print(f"获取用户资料字典失败: {str(e)}")
            return {}
    
    @classmethod
    def get_mate_criteria_dicts(cls) -> Dict[str, List[Dict[str, Any]]]:
        """获取择偶条件相关的所有字典"""
        try:
            result = {}
            
            for dict_code in cls.MATE_CRITERIA_DICTS:
                items = cls.get_dict_items(dict_code)
                if items:
                    result[dict_code] = items
            
            return result
            
        except Exception as e:
            print(f"获取择偶条件字典失败: {str(e)}")
            return {}
    
    @classmethod
    def get_dict_item_by_value(cls, dict_code: str, item_value: str) -> Optional[Dict[str, Any]]:
        """根据字典编码和项值获取字典项"""
        try:
            category = DictCategory.query.filter_by(
                dict_code=dict_code, 
                is_active=True
            ).first()
            
            if not category:
                return None
            
            item = DictItem.query.filter_by(
                dict_id=category.id,
                item_value=item_value,
                is_active=True
            ).first()
            
            return item.to_dict() if item else None
            
        except Exception as e:
            print(f"获取字典项失败: {str(e)}")
            return None
    
    @classmethod
    def get_dict_text_by_value(cls, dict_code: str, item_value: str) -> str:
        """根据字典编码和项值获取字典项的显示文本"""
        item = cls.get_dict_item_by_value(dict_code, item_value)
        return item['item_name'] if item else item_value
    
    @classmethod
    def validate_dict_value(cls, dict_code: str, item_value: str) -> bool:
        """验证字典值是否有效"""
        item = cls.get_dict_item_by_value(dict_code, item_value)
        return item is not None
    
    @classmethod
    def validate_dict_values(cls, dict_code: str, item_values: List[str]) -> Dict[str, bool]:
        """批量验证字典值是否有效"""
        result = {}
        for value in item_values:
            result[value] = cls.validate_dict_value(dict_code, value)
        return result
    
    @classmethod
    def format_dict_values_text(cls, dict_code: str, item_values: List[str]) -> List[str]:
        """将字典值列表转换为显示文本列表"""
        result = []
        for value in item_values:
            text = cls.get_dict_text_by_value(dict_code, value)
            result.append(text)
        return result
    
    @classmethod
    def parse_json_dict_values(cls, json_str: str) -> List[str]:
        """解析JSON字符串为字典值列表"""
        if not json_str:
            return []
        
        try:
            values = json.loads(json_str)
            if isinstance(values, list):
                return values
            elif isinstance(values, str):
                return [values]
            else:
                return []
        except (json.JSONDecodeError, TypeError):
            return []
    
    @classmethod
    def format_json_dict_values_text(cls, dict_code: str, json_str: str) -> List[str]:
        """将JSON字符串中的字典值转换为显示文本列表"""
        values = cls.parse_json_dict_values(json_str)
        return cls.format_dict_values_text(dict_code, values)
    
    @classmethod
    def get_dict_statistics(cls) -> Dict[str, Any]:
        """获取字典统计信息"""
        try:
            total_categories = DictCategory.query.filter_by(is_active=True).count()
            total_items = db.session.query(DictItem)\
                                   .join(DictCategory)\
                                   .filter(DictCategory.is_active == True,
                                          DictItem.is_active == True)\
                                   .count()
            
            # 按用途分组统计
            user_profile_count = len(cls.USER_PROFILE_DICTS)
            mate_criteria_count = len(cls.MATE_CRITERIA_DICTS)
            common_count = total_categories - user_profile_count - mate_criteria_count
            
            return {
                'total_categories': total_categories,
                'total_items': total_items,
                'user_profile_categories': user_profile_count,
                'mate_criteria_categories': mate_criteria_count,
                'common_categories': common_count
            }
            
        except Exception as e:
            print(f"获取字典统计信息失败: {str(e)}")
            return {}
    
    @classmethod
    def search_dict_items(cls, keyword: str, dict_codes: Optional[List[str]] = None) -> List[Dict[str, Any]]:
        """搜索字典项"""
        try:
            query = db.session.query(DictItem)\
                             .join(DictCategory)\
                             .filter(DictCategory.is_active == True,
                                    DictItem.is_active == True)
            
            # 按字典分类过滤
            if dict_codes:
                query = query.filter(DictCategory.dict_code.in_(dict_codes))
            
            # 按关键词搜索
            if keyword:
                query = query.filter(
                    db.or_(
                        DictItem.item_name.like(f'%{keyword}%'),
                        DictItem.item_value.like(f'%{keyword}%'),
                        DictCategory.dict_name.like(f'%{keyword}%')
                    )
                )
            
            items = query.order_by(DictCategory.sort_order, DictItem.sort_order).all()
            
            return [item.to_dict() for item in items]
            
        except Exception as e:
            print(f"搜索字典项失败: {str(e)}")
            return [] 